import sys
import os
import wx

from threading import Thread
from shutil import copy

from BitTornado.__init__ import product_name, version_short, build_number, author
from BitTornado.zurllib import urlopen
from baseaction import ActionMenu, Action

from LMG.Tools.templatesgui import TemplatesDialog
from LMG.Tools.webservicegui import WebDialog
from LMG.Tools.btmaketorrentgui import TorrentMaker
from LMG.Tools.cmdschedulergui import CommandSchedulerDialog
from LMG.GUI.preferences import PreferencesDialog
from LMG.GUI.Base.ArtManager import ArtManager
from LMG.GUI.Base.menu import Menu


from LMG.Utility.helpers import stopTorrentsIfNeeded
from LMG.Utility.constants import *

##########################################################################
#   Menus
##########################################################################
class FileMenu(ActionMenu):
    """
    File Menu (in Menu Bar)
    """
    def __init__(self):
        subactions = [ACTION_MENU_ADDTORRENT,
                      ACTION_MAKER,
                      ACTION_PREFERENCES,
                      -1,
#                      ACTION_RESTART,
                      ACTION_EXIT,
                      ]
        
        ActionMenu.__init__(self, 
                            menudesc = _('&File'), 
                            subactions = subactions)
        
class ToolsMenu(ActionMenu):
    """
    File Menu (in Menu Bar)
    """
    def __init__(self):
        subactions = [ACTION_CMDSCHEDULERDIALOG,
                      ACTION_TEMPLATESDIALOG,
                      ACTION_WEBDIALOG,
                      ]
        
        ActionMenu.__init__(self, 
                            menudesc = _('&Tools'), 
                            subactions = subactions)

class ViewMenu(ActionMenu):
    """
    View Menu (in Menu Bar)
    """
    def __init__(self):
        subactions = [ACTION_VIEWTRANSFER,
                      ACTION_VIEWRSS,
                      ACTION_VIEWSEARCH,
                      ACTION_VIEWLOG,
                      -1,
                      ACTION_VIEWTOOLBAR,
                      ACTION_VIEWSTATUSBAR,
                      ACTION_TORRENTDETAILS,
                      ]
        
        if wx.Platform == "__WXMSW__":
            subactions.extend([-1, ACTION_THEME])
        else:
            subactions.insert(6, ACTION_CUSTOMIZE_TOOLBAR)

        ActionMenu.__init__(self, 
                            menudesc = _('&View'), 
                            subactions = subactions)

class EditMenu(ActionMenu):
    """
    Edit Menu (in Menu Bar)
    """
    def __init__(self):
        subactions = [ACTION_STOPALL,
                      ACTION_UNSTOPALL,
                      ACTION_QUEUEACTIVE,
                      ACTION_CLEARALL,
                      -1,
                      ACTION_MENUTOOLS,
                      ACTION_ONIDLE,
                      ]
        ActionMenu.__init__(self, 
                            menudesc = _('&Edit'), 
                            subactions = subactions)
        
class HelpMenu(ActionMenu):
    """
    Help Menu (in Menu Bar)
    """
    def __init__(self):
        subactions = [ACTION_UPDATECHECK,
                      ACTION_HOMEPAGE,
                      ACTION_ABOUT,
                      ]
        
        ActionMenu.__init__(self, 
                            menudesc = _('&Help'), 
                            subactions = subactions,
                            id = wx.ID_HELP)
        
        wx.App_SetMacHelpMenuTitleName(self.menudesc)

class AddTorrentMenu(ActionMenu):
    """
    Show the menu of ways to add a torrent
    """
    def __init__(self):
        subactions = [ACTION_ADDTORRENTFROMFILE, 
                      ACTION_ADDTORRENTNONDEFAULT, 
                      ACTION_ADDTORRENTURL,
                      -1,
                      ACTION_SCANTORRENTDIR,
                      ACTION_SCANURL]
        
        ActionMenu.__init__(self,
                           'addtorrent.png',
                            shortdesc = _('Open'),
                            menudesc = _('&Open Torrent'),
                            subactions = subactions,
			    id = wx.ID_OPEN)
        
    def action(self, event = None):
        utility.actions[ACTION_ADDTORRENTFROMFILE].action()

##########################################################################
#   Base Actions
##########################################################################

class Exit(Action):
    """
    Exit the application
    """
    def __init__(self):
        Action.__init__(self,
                        shortdesc = _('Exit'),
                        menudesc = _('&Quit')+'\tCtrl-Q', 
                        id = wx.ID_EXIT)
                           
    def action(self, event = None):
        utility.frame.OnCloseWindow()

class Preferences(Action):
    """
    Open preferences dialog
    """
    def __init__(self):
        Action.__init__(self, 
			'preferences.png', 
                        menudesc = _('&Preferences')+'\tCtrl+P',
                        shortdesc = _('Options'),
                        id = wx.ID_PREFERENCES)

    def action(self, event = None):
##        g = utility.torrents.keys()
##        c = g.index(utility.activeGroup)
##        utility.queue.filterGroups(g[(c+1)%len(g)])
##        return
        if utility.frame.preferences is None:
            utility.frame.preferences = PreferencesDialog(utility.window)
        utility.frame.preferences.Raise()
        
class UpdateCheck(Action):
    """
    update
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('&Check For Updates'))
                           
    def action(self, event = None):
        wx.LogMessage('Checking for new version...')
        t = Thread(target=self._checkForNewVersion, args=[event!=None])
        t.setDaemon(True)
        t.start()
        
    def _checkForNewVersion(self, manual):        
        try:
            url = "http://lh-abc.googlecode.com/svn/trunk/LATEST"
            h = urlopen(url)
            ver_content = h.read()
            ver_content = ver_content.split(';')
            assert len(ver_content) >= 3
            if int(ver_content[0]) > build_number:
                wx.CallAfter(self.OnNewVersion, ver_content[1], ver_content[2], manual)
            else:
                wx.CallAfter(self.OnUpdateMessage, _('You already have the latest version'), manual)
        except:
            wx.CallAfter(self.OnUpdateMessage, _('Could not connect to web server'), manual)
                
    def OnUpdateMessage(self, message, manual):
        if not manual:
            wx.LogMessage(message)
            return
        dlg = wx.MessageDialog(utility.window, message, _('Update Info'), wx.OK)
        dlg.ShowModal()
        dlg.Destroy()
        
    def OnNewVersion(self, new_version, new_notes, manual):
        dlg = wx.MessageDialog(utility.window, _('There is a new version available: ') + new_version + "\n" + \
                               _('Version notes:') + "\n" + new_notes + "\n" + \
                               _('Would you like to visit the project site?'),
                               _('Update Info'), wx.YES_NO)
        result = dlg.ShowModal()
        dlg.Destroy()
        
        if result == wx.ID_YES:
            utility.actions[ACTION_HOMEPAGE].action()
            
class HomePage(Action):
    """
    Go to homepage
    """
    def __init__(self):
        Action.__init__(self,
                        id = wx.ID_HOME,
                        menudesc = _('&Home Page'))
                           
    def action(self, event = None):
        wx.LaunchDefaultBrowser(utility.config.Read("homepage")) 

class About(Action):
    """
    Open about dialog
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('&About'),
                        id = wx.ID_ABOUT)

    def action(self, event = None):
        major, minor, micro, releaselevel, serial = sys.version_info
        python_version = str(major) + "." + str(minor) + "." + str(micro)
        desc = _("%s is a BitTorrent client based on ABC\nPowered by Python %s, wxPython %s.\n") % (product_name, python_version, wx.VERSION_STRING)      
        desc += _("Special thanks to Martin Erdner!")
        info = wx.AboutDialogInfo()
        info.Name = product_name
        info.Version = version_short
        info.Description = desc
        info.Copyright = u"\u00A9 2007-2008 " + author
        info.Developers = [author,
                           "Tim Tucker (ABC)",
                           "Old King Cole (ABC_OKC)",
                           "NoirSoldats (ABC)",
                           "Choopan Rattanapoka (ABC)",
                           "John Hoffman (BitTornado)"]
        info.Artists = ["Kaya Unal"]
            
        if wx.Platform == "__WXMSW__": # Make Generic
            info.WebSite = (utility.config.Read("homepage"), _("Project Page"))
            
        elif wx.Platform == "__WXGTK__": # Support all
            info.WebSite = (utility.config.Read("homepage"), _("Project Page"))
            try:
                licensefile = open(os.path.join(utility.getSharePath(), "LICENSE.txt"), "r")
                info.License = "".join(licensefile.readlines())
                licensefile.close()
            except:
                info.License = "Unless otherwise noted, all files are released under the MIT license, \n" + \
                                "exceptions contain licensing information in them."
            try:
                translatorsfile = open(os.path.join(utility.getSharePath(), 'locale', 'translators.list'), "r")
                info.Translators = translatorsfile.readlines()
                translatorsfile.close()
            except:
                pass
                
        wx.AboutBox(info)
        
##########################################################################
#   Tools Actions
##########################################################################
class CommandScheduler(Action):
    """
    Enable/Disable Command Scheduler
    """
    def __init__(self):
        Action.__init__(self,
                        'cmdscheduler.png',
                        menudesc = _('Toggle &Command Scheduler'),
                        shortdesc = _('Scheduler'),
                        kind = wx.ITEM_CHECK)
        
    def action(self, event = None):
        commandScheduler = utility.frame.commandScheduler
        if commandScheduler.running:
            commandScheduler.stop()
        else:
            commandScheduler.start()
        self.updateButton()
        
    def updateButton(self):
        commandScheduler = utility.frame.commandScheduler
        active = commandScheduler.running

        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
                
                if active:
                    toolstring = _('Command Scheduler Active')
                else:
                    toolstring = _('Command Scheduler Inactive')
                toolbar.SetToolShortHelp(self.id, toolstring)
                toolbar.SetToolLongHelp(self.id, toolstring)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
            
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

class CommandSchedulerPreferences(Action):
    """
    Open Command Scheduler dialog
    """
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('&Command Scheduler'),
                        shortdesc = _('Command Scheduler'))
        
    def action(self, event = None):
        dlg = CommandSchedulerDialog(utility.frame)
        dlg.ShowModal()
        dlg.Destroy()
        
class Templates(Action):
    """
    Open the templates dialog
    """
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('&Templates'),
                        shortdesc = _('Templates'))
        
    def action(self, event = None):
        d = TemplatesDialog(utility.frame)
        d.ShowModal()
        d.Destroy()


class WebService(Action):
    """
    Enable/Disable Web Service
    """
    def __init__(self):
        Action.__init__(self, 
                        'webservice.png',
                        menudesc = _('Toggle &Web Service'),
                        shortdesc = _('Web'),
                        kind = wx.ITEM_CHECK)
        
    def action(self, event = None, activate = None):
        # Make changes?
        if activate is not None and \
           activate == utility.webserver.active:
            return
        # Toggle
        if utility.webserver.active:
            utility.webserver.stop()
        else:
            utility.webserver.start()
    
    def updateButton(self):
        active = utility.webserver.active
        
        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
                
                if active:
                    toolstring = _('Web Service Active')
                else:
                    toolstring = _('Web Service Inactive')
                toolbar.SetToolShortHelp(self.id, toolstring)
                toolbar.SetToolLongHelp(self.id, toolstring)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
            
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)
            
class WebServicePreferences(Action):
    """
    Open dialog for web service preferences
    """
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('&Web Service'),
                        shortdesc = _('Web Service'))                           
                           
    def action(self, event = None):
        dialog = WebDialog(utility.frame)
        dialog.ShowModal()
        dialog.Destroy()


class DirectoryScanner(Action):
    """
    Start/Stop the Directory Scanner
    """
    def __init__(self):
        Action.__init__(self,
                        'scanner.png',
                        menudesc = _('&Directory Scanner'),
                        shortdesc = _('Scanner'),
                        kind = wx.ITEM_CHECK)
        
    def action(self, event = None):
        active = not utility.config.Read('scandiractive', "boolean")
        utility.config.Write('scandiractive', active, "boolean")
        if active:
            utility.queue.lastDirScan = 0
        self.updateButton(active)
            
    def updateButton(self, active = None):
        if active is None:
            active = utility.config.Read('scandiractive', "boolean")
        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

        
class MakeTorrent(Action):
    """
    Open torrent maker.
    """
    def __init__(self):
        Action.__init__(self,
                        'maker.png',
                        shortdesc = _('New'),
                        longdesc = _('Create a new .torrent file'),
                        menudesc = _('&New Torrent')+'\tCtrl+N',
			id = wx.ID_NEW
                        )
                           
        self.torrentmaker = None
                           
    def action(self, event = None):
        self.torrentmaker = TorrentMaker(utility.frame)
        
    def closeWin(self):
        try:
            if self.torrentmaker is not None:
                self.torrentmaker.closeWin()
        except wx.PyDeadObjectError:
            pass

class OnIdle(Action):
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('When &Idle'))
                           
        self.idleoptions = [ _('Do &Nothing'), 
                            _('&Close Client'),
                            _('&Shutdown Computer')]
        self.idleID = []
        for i in range(len(self.idleoptions)):
            self.idleID.append(wx.NewId())
        
    def action(self, event):
        eventid = event.GetId()
        newwhenidle = None
        for i in range(len(self.idleID)):
            id = self.idleID[i]
            if id == eventid:
                newwhenidle = i
                break
            
        if newwhenidle is not None:
            utility.queue.whenidle = newwhenidle
            utility.queue.checkIdleForClosing()
            self.CheckNeeded()

    def getCurrentIdle(self):
        return self.idleID[utility.queue.whenidle]
               
    def addToMenu(self, menu, bindto = None):
        if bindto is None:
            bindto = menu
            
        currentidleop = self.getCurrentIdle()
        if currentidleop is None:
            return
            
        idleMenu = Menu()
        for i in xrange(len(self.idleoptions)):
            id = self.idleID[i]
            bindto.Bind(wx.EVT_MENU, self.action, id = id)
            if wx.Platform == "__WXGTK__":
                idleMenu.Bind(wx.EVT_MENU, self.action, id = id)
            idleMenu.Append(id, self.idleoptions[i], self.idleoptions[i], wx.ITEM_RADIO)
        if sys.platform != 'win32':
            id = wx.NewId()
            idleMenu.AppendSeparator()
            idleMenu.Append(id, _('Set Shutdown Command'))
            bindto.Bind(wx.EVT_MENU, utility.setShutdownCommand, id = id)

        idleMenu.Check(currentidleop, True)
        menu.AppendMenu(self.id, self.menudesc, idleMenu)
        
        if not idleMenu in self.menus and not isinstance(bindto, wx.Menu):
            self.menus.append(idleMenu)
        
        return self.id
    
    def CheckNeeded(self):
        for menu in self.menus:
            try:
                menu.Check(self.getCurrentIdle(), True)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

class TemplatesMenu(Action):
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('&Template'))
        self.templatesMenu = None
        self.clearID = wx.NewId()
        
    def action(self, event = None):
        list = utility.window.list
        selected = list.getTorrentSelected()
        label = self.templatesMenu.GetLabelText(event.GetId())

        if label is None:
            return
        
        for torrent in selected:
            torrent.connection.applyLabel(label)
        utility.window.details.updateSettings()
        utility.queue.updateAndInvoke()
        list.SetFocus()

    def clear(self, event = None):
        list = utility.window.list
        selected = list.getTorrentSelected()
        for torrent in selected:
            torrent.connection.clearLabel()
        list.SetFocus()
        
    def addToMenu(self, menu, bindto = None):
        if bindto is None:
            bindto = menu
            
        self.makeMenu(bindto)
        menu.AppendMenu(self.id, self.menudesc, self.templatesMenu)
        
        return self.id

    def makeMenu(self, bindto):
        selected = utility.window.list.getTorrentSelected()
        templates = list(utility.labelmanager.l_templates)

        title = _("Templates")
        if len(selected) == 1 and selected[0].files.getActiveLabel():
            title += " (" + selected[0].files.getActiveLabel() + ")"
        self.templatesMenu = Menu(title=title)
        for template in templates:
            obj = utility.labelmanager.get(template)
            if not obj or obj.hidelabel:
                continue            
            id = wx.NewId()
            bindto.Bind(wx.EVT_MENU, self.action, id = id)
            if wx.Platform == "__WXGTK__":
                self.templatesMenu.Bind(wx.EVT_MENU, self.action, id = id)
            self.templatesMenu.Append(id, template, template, wx.ITEM_NORMAL)
        self.templatesMenu.AppendSeparator()
        self.templatesMenu.Append(self.clearID, _("Clear"), _("Disable active label. Local settings unchanged"), wx.ITEM_NORMAL)
        bindto.Bind(wx.EVT_MENU, self.clear, id = self.clearID)
        if wx.Platform == "__WXGTK__":
            self.templatesMenu.Bind(wx.EVT_MENU, self.clear, id = self.clearID)

#########################################################################
#   Add/Remove torrents
#########################################################################
class AddTorrentFile(Action):
    """
    Add a torrent file
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('From File')+'\tCtrl+O'
			)
        
    def action(self, event = None):
        utility.queue.addtorrents.AddTorrentFile()

class AddTorrentNonDefault(Action):
    """
    Add a torrent to a non-default location
    """
    def __init__(self):
        Action.__init__(self, 
                        shortdesc = _('Open From File (non default location)'),
                        menudesc = _('From File (non default location)')+'\tCtrl+Shift+O')
                           
    def action(self, event = None):
        utility.queue.addtorrents.AddTorrentNoneDefault()

class AddTorrentURL(Action):
    """
    Add a torrent from a URL
    """
    def __init__(self):
        Action.__init__(self,
                        shortdesc = _('Open From URL'),
                        menudesc = _('From URL')+'\tCtrl+U')
                           
    def action(self, event = None):
        utility.queue.addtorrents.AddTorrentLink()
               
class ScanTorrentDir(Action):
    """
    Scans a directory for .torrent files
    """
    def __init__(self):
        Action.__init__(self,
                        shortdesc = _('Scan Directory'),
                        menudesc = _('Scan Directory'))

    def action(self, event = None):
        utility.queue.addtorrents.OnScanTorrentDir()
        
class ScanURL(Action):
    """
    Scans a directory for .torrent files
    """
    def __init__(self):
        Action.__init__(self,
                        shortdesc = _('Scan URL'),
                        menudesc = _('Scan URL'))

    def action(self, event = None):
        utility.queue.addtorrents.OnScanURL()

class Remove(Action):
    """
    Remov torrents from the list
    """
    def __init__(self):
        Action.__init__(self, 
                        'remove.png', 
                        _('Remove'),
                        longdesc = _('Removes torrent from list'), 
                        menudesc = _('Remove Torrent')+'\tShift+Del',
                        )
                           
    def action(self, event = None, removefiles = False, caller=""):
        self.remove(None, removefiles, caller)
        
    def remove(self, torrentselected = None, removefiles = False, caller=""):
        list = utility.window.list
        
        if utility.queue.ratemanager.doneflag.isSet():
            # RateManager is running : We record the event
            # It will be run after these tasks have completed
            if list.IsEnabled():
                list.Disable()

            utility.window.postponedevents.append((self.remove, torrentselected, removefiles, caller))
            return

        if torrentselected is None:
            torrentselected = list.getTorrentSelected(reverse = True)
        
        if not torrentselected:
            return

        if removefiles and caller not in ["web", "command"]:
            # Display Dialog Warning
            ##############################
            dialog = wx.MessageDialog(None, 
                                      _("Are you sure you want to delete these files?\nAll data will be lost!\n"), 
                                      _('Warning'), 
                                      wx.ICON_WARNING|wx.YES_NO)
            result = dialog.ShowModal()
            dialog.Destroy()
            if(result == wx.ID_NO):            
                return

        firstselected = torrentselected[-1].listindex

        # Stop all the files first
        utility.actionhandler.procSTOP(torrentselected)

        # Remove the torrents from the list
        # (and remove files if necessary)
        utility.actionhandler.procREMOVE(torrentselected, removefiles)
        
        listsize = list.GetItemCount() - 1
        
        if listsize >= 0:
            if firstselected >= listsize:
                list.Select(listsize)
            else:
                list.Select(firstselected)
        list.SetFocus()
        
    def command(self, command):
        feedback = {}
        torrents = utility.commands.getTorrentsFromCommand(command)
        self.remove(torrents, removefiles = False, caller = "web")
        return feedback

class RemoveFile(Action):
    """
    Remov torrents along with their files
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Remove Torrent and Files'),
			id = wx.ID_DELETE)
                           
    def action(self, event = None, caller=""):
        utility.actions[ACTION_REMOVE].action(removefiles = True, caller=caller)
                        
    def command(self, command):
        feedback = {}
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actions[ACTION_REMOVE].remove(torrents, removefiles = True, caller = "web")
        return feedback       

##########################################################################
#   View Actions
##########################################################################

class PageSelection(Action):
    """
    View the Transfer list
    """
    def __init__(self):
        Action.__init__(self,
                        'transfer.png',
                        shortdesc = _('Pager'),
                        )
        
        if 'mainToggle' in utility.actionGroup:
            utility.actionGroup['mainToggle'].append(self)
        else:
            utility.actionGroup['mainToggle'] = [self]
                           
    def action(self, event = None):
        menu = Menu()
        subactions = (ACTION_VIEWTRANSFER, ACTION_VIEWRSS, ACTION_VIEWSEARCH, ACTION_VIEWLOG)
        for action in subactions:
            utility.actions[action].addToMenu(menu, forceBitmap = True)
        utility.window.PopupMenu(menu)

        self.updateButton()

    def updateButton(self, active = None):
        if utility.window['transfer'].IsShown():
            action = ACTION_VIEWTRANSFER
        elif utility.window['rss'].IsShown():
            action = ACTION_VIEWRSS
        elif utility.window['search'].IsShown():
            action = ACTION_VIEWSEARCH
        elif utility.window['log'].IsShown():
            action = ACTION_VIEWLOG
        else:
            return
        
        for toolbar in self.toolbars:
            try:
                toolbar.SetToolNormalBitmap(self.id, utility.actions[action].bitmap)
                tool = toolbar.FindById(self.id)
                if tool:
                    tool.SetLabel(utility.actions[action].shortdesc)
                    toolbar.Realize()            
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)

class ViewTransfer(Action):
    """
    View the Transfer list
    """
    def __init__(self):
        Action.__init__(self,
                        'transfer.png',
                        shortdesc = _('Transfers'),
                        menudesc = _('&Transfers')+'\tCtrl+T',
                        kind = wx.ITEM_RADIO,
                        )
                           
        if 'mainToggle' in utility.actionGroup:
            utility.actionGroup['mainToggle'].append(self)
        else:
            utility.actionGroup['mainToggle'] = [self]

    def action(self, event = None):
        utility.window.selectPage('transfer')
        self.updateButton()

    def updateButton(self, active = None):
        if active is None:
            active = utility.window['transfer'].IsShown()

        toChange = [ACTION_RESUME, ACTION_STOP, ACTION_PAUSE, ACTION_QUEUE,
                    ACTION_SCRAPE, ACTION_REMOVE,
                    ACTION_MOVEUP, ACTION_MOVEDOWN, ACTION_MOVETOP, ACTION_MOVEBOTTOM]
        for a in toChange:
            utility.actions[a].enableTool(active)

        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)
        if active:
            for action in utility.actionGroup['mainToggle']:
                if action != self:
                    action.updateButton(False)
            
class ViewRss(Action):
    """
    View the RSS page
    """
    def __init__(self):
        Action.__init__(self,
                        'rss.png',
                        shortdesc = _('RSS'),
                        menudesc = _('&RSS')+'\tCtrl+R',
                        kind = wx.ITEM_RADIO,
                        )
        
        if 'mainToggle' in utility.actionGroup:
            utility.actionGroup['mainToggle'].append(self)
        else:
            utility.actionGroup['mainToggle'] = [self]
                           
    def action(self, event = None):
        utility.window.selectPage('rss')
        self.updateButton()

    def updateButton(self, active = None):
        if active is None:
            active = utility.window['rss'].IsShown()
        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)
        if active:
            for action in utility.actionGroup['mainToggle']:
                if action != self:
                    action.updateButton(False)
                    
class ViewSearch(Action):
    """
    View the Search page
    """
    def __init__(self):
        Action.__init__(self,
                        'search.png',
                        shortdesc = _('Search'),
                        menudesc = _('&Search')+'\tCtrl+E',
                        kind = wx.ITEM_RADIO,
                        )
        
        if 'mainToggle' in utility.actionGroup:
            utility.actionGroup['mainToggle'].append(self)
        else:
            utility.actionGroup['mainToggle'] = [self]
                           
    def action(self, event = None):
        utility.window.selectPage('search')
        self.updateButton()

    def updateButton(self, active = None):
        if active is None:
            active = utility.window['search'].IsShown()
        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, active)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)
        if active:
            for action in utility.actionGroup['mainToggle']:
                if action != self:
                    action.updateButton(False)

class ViewLog(Action):
    """
    View the Log page
    """
    def __init__(self):
        Action.__init__(self,
                        'log.png',
                        shortdesc = _('Log'),
                        menudesc = _('&Log')+'\tCtrl+L',
                        kind = wx.ITEM_RADIO,
                        )
        
        if 'mainToggle' in utility.actionGroup:
            utility.actionGroup['mainToggle'].append(self)
        else:
            utility.actionGroup['mainToggle'] = [self]
                           
    def action(self, event = None):
        utility.window.selectPage('log')
        self.updateButton()

    def updateButton(self, active = None):
        if active is None:
            active = utility.window['log'].IsShown()
        for toolbar in self.toolbars:
            toolbar.ToggleTool(self.id, active)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(active)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)
        if active:
            for action in utility.actionGroup['mainToggle']:
                if action != self:
                    action.updateButton(False)

class CustomizeToolbar(Action):
    """
    Customize the main toolbar
    """
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('Customize Toolbar'),
                        shortdesc = _('Customize Toolbar'))

    def action(self, event = None):
        utility.frame.tb.onToolbarDialog()

class ViewToolbar(Action):
    """
    View/Hide the main toolbar
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Show &Toolbar')+'\tCtrl+Alt+T',
                        shortdesc = _('Toggle Toolbar'),
                        kind = wx.ITEM_CHECK)

    def action(self, event = None):
        if utility.frame.tb.IsShown():
            utility.frame.tb.Show(False)
        else:
            utility.frame.tb.Show()

        self.updateCheck()
        utility.frame._Refresh()

    def updateCheck(self, reverse=False):
        if utility.frame.tb.IsShown():
            reverse = not reverse
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(reverse)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

class ViewStatusbar(Action):
    """
    View/Hide the main toolbar
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Show &StatusBar')+'\tCtrl+Alt+S',
                        shortdesc = _('Toggle StatusBar'),
                        kind = wx.ITEM_CHECK)

    def action(self, event = None):
        if utility.frame.StatusBar.IsShown():
            utility.frame.StatusBar.Show(False)
        else:
            utility.frame.StatusBar.Show()

        self.updateCheck()
        
        utility.frame._Refresh()

    def updateCheck(self, reverse=False):
        if utility.frame.StatusBar.IsShown():
            reverse = not reverse
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(reverse)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

class Theme(Action):
    """
    Set Theme Color
    """
    def __init__(self):
        Action.__init__(self, 
                        shortdesc = _('Set Theme &Colour'))
        self.colour = None
        
    def action(self, event = None):
        data = wx.ColourData()
        data.SetColour(ArtManager.Get().getThemeColor())
        dlg = wx.ColourDialog(utility.window, data)
        dlg.GetColourData().SetChooseFull(False)
        if dlg.ShowModal() == wx.ID_OK:
            data = dlg.GetColourData()
        dlg.Destroy()
        utility.config.Write('theme_color', data.GetColour(), "color")
        self.update()
        
    def update(self):
        color = ArtManager.Get().getThemeColor()
        utility.frame.GetToolBar().SetGradientBackground(color)

        if ArtManager.Get().isDefTheme():
            self.colour = None
        elif ArtManager.Get().IsDark(color):
            self.colour = ArtManager.Get().LightColour(color, 60)
        else:
            self.colour = ArtManager.Get().LightColour(color, 45)
                
        # MenuBar
        utility.frame.MenuBar.ChangeMenuBarColor()
        
        # All pages
        for page in utility.window.getPages():
            self.setBackground(page)

        # All lists
        for list in utility.lists:
            if list not in utility.window.getPages():
                self.setBackground(list)
            ArtManager.Get().MakeAlternateList(list)
            
    def setBackground(self, page):
        if self.colour:
            page.SetBackgroundColour(self.colour)
        else:
            default = page.GetDefaultAttributes()
            page.SetBackgroundColour(default.colBg)
        page.Refresh()
        
class TorrentInspector(Action):
    """
    View torrent details page
    """
    def __init__(self):
        Action.__init__(self,
                        'info.png',
                        menudesc = _('Torrent &Inspector')+'\tCtrl+I',
                        shortdesc = _('Inspector'),
                        kind = wx.ITEM_CHECK,
                        )

    def isFramed(self):
        return utility.window.details.GetParent() == utility.window.detailsFrame
    
    def changeParent(self):
        show = utility.window.details.IsShown()
        if self.isFramed():
            utility.window.details.EnableDockButton(False)
            utility.window.details.Reparent(utility.window.splitter)
        else:
            utility.window.details.EnableDockButton(True)
            utility.config.Write("splitter_pos", utility.window.splitter.GetSashPosition(), "int")
            utility.window.splitter.Unsplit(utility.window.details)
            utility.window.details.Reparent(utility.window.detailsFrame)
        self.action(show = show)                
            
    def action(self, event = None, show = None):
        if show is None:
            show = not utility.window.details.IsShown()

        if self.isFramed():
            if show:
                utility.window.detailsFrame.Show()
                utility.window.details.Show()
                utility.window.detailsFrame.SendSizeEvent()
                wx.CallAfter(utility.window.detailsFrame.Raise)
            else:
                utility.window.detailsFrame.Hide()
                utility.window.details.Hide()
        else:
            utility.window.detailsFrame.Hide()
            if show:
                utility.window.splitter.SplitHorizontally(utility.window.list, utility.window.details, utility.config.Read('splitter_pos', "int"))
                utility.window.list.EnsureSelectedVisible()
            else:
                utility.config.Write("splitter_pos", utility.window.splitter.GetSashPosition(), "int")
                utility.window.splitter.Unsplit(utility.window.details)
         
        self.updateButton(show)
        
    def updateButton(self, shown = None):
        if shown is None:
            shown = utility.window.details.IsShown()
        for toolbar in self.toolbars:
            try:
                toolbar.ToggleTool(self.id, shown)
            except wx.PyDeadObjectError:
                self.toolbars.remove(toolbar)
        for menu in self.menus:
            try:
                item = menu.FindItemById(self.id)
                if item.IsCheckable():
                    item.Check(shown)
            except wx.PyDeadObjectError:
                self.menus.remove(menu)

##########################################################################
#   Status
##########################################################################
class StopAll(Action):
    def __init__(self):
        Action.__init__(self,
                        id = wx.ID_STOP,
                        shortdesc = _('Stop All'),
                        menudesc = _('&Stop All'))
        
    def action(self, event = None):
        utility.actionhandler.procSTOP()
        utility.window.list.SetFocus()     

    def command(self, command):        
        feedback = {}
        utility.actionhandler.procSTOP()
        return feedback

class UnStopAll(Action):
    def __init__(self):
        Action.__init__(self,
                        id = wx.ID_REFRESH,
                        shortdesc = _('Queue Stopped'),
                        menudesc = _('&Queue Stopped'))
        
    def action(self, event = None):
        utility.actionhandler.procUNSTOP()
        utility.window.list.SetFocus()
        
    def command(self, command):        
        feedback = {}
        utility.actionhandler.procUNSTOP()
        return feedback

class QueueActive(Action):
    def __init__(self):
        Action.__init__(self,
                        id = wx.ID_RESET,
                        shortdesc = _('Enforce Queue Limit'),
                        menudesc = _('&Enforce Queue Limit'))
        
    def action(self, event = None):
        maxallowed  = utility.config.Read('numsimdownload', "int")
        torrentstoqueue = utility.queue.getProcCount() - maxallowed
        if torrentstoqueue > 0:
            utility.actionhandler.procQUEUE(utility.queue.getActiveTorrents(torrentstoqueue))
        utility.window.list.SetFocus()
        
    def command(self, command):        
        feedback = {}
        maxallowed  = utility.config.Read('numsimdownload', "int")
        torrentstoqueue = utility.queue.getProcCount() - maxallowed
        if torrentstoqueue > 0:
            utility.actionhandler.procQUEUE(utility.queue.getActiveTorrents(torrentstoqueue))
        return feedback

class ClearCompleted(Action):
    def __init__(self):
        Action.__init__(self,
                        id = wx.ID_CLEAR,
                        shortdesc = _('Clear Completed'),
                        menudesc = _('&Clear Completed'))
        
    def action(self, event = None, caller = ""):
        list = utility.window.list
        
        if utility.queue.ratemanager.doneflag.isSet():
            # RateManager is running : We record the event
            # It will be run after these tasks have completed
            if list.IsEnabled():
                list.Disable()
            utility.window.postponedevents.append((self.action, event, caller))
        else:
            utility.queue.clearAllCompleted()
            list.SetFocus()
            
    def command(self, command):        
        feedback = {}        
        self.action(caller="web")        
        return feedback

class Resume(Action):
    def __init__(self):
        Action.__init__(self, 
                        'resume.png', 
                        _('Resume'),
                        menudesc = _('Resume')+'\tShift+R',
                        )
                        
    def action(self, event = None):
        utility.actionhandler.procRESUME(utility.window.list.getTorrentSelected())
        utility.window.list.SetFocus()

    def command(self, command):        
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actionhandler.procRESUME(torrents)
        return feedback

class Pause(Action):
    def __init__(self):
        Action.__init__(self, 
                        'pause.png', 
                         _('Pause'),
                        menudesc = _('Pause')+'\tShift+P',
                        )
                           
    def action(self, event = None):
        utility.actionhandler.procPAUSE(utility.window.list.getTorrentSelected())
        utility.window.list.SetFocus()

    def command(self, command):
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actionhandler.procPAUSE(torrents)
        return feedback        

class Stop(Action):
    def __init__(self):
        Action.__init__(self, 
                        'stop.png', 
                         _('Stop'),
                        menudesc = _('Stop')+'\tShift+S',
                        )
                           
    def action(self, event = None):
        utility.actionhandler.procSTOP(utility.window.list.getTorrentSelected())
        utility.window.list.SetFocus()

    def command(self, command, caller=""):        
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actionhandler.procSTOP(torrents)
        return feedback        

class Queue(Action):
    def __init__(self):
        Action.__init__(self, 
                        'queue.png', 
                        _('Queue'),
                        menudesc = _('Queue')+'\tShift+Q',
                        )
                           
    def action(self, event = None):
        utility.actionhandler.procQUEUE(utility.window.list.getTorrentSelected())
        utility.window.list.SetFocus()

    def command(self, command):        
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actionhandler.procQUEUE(torrents)
        return feedback        
               
class SuperSeed(Action):
    def __init__(self):
        Action.__init__(self, 
                        shortdesc = _('Super Seed'))
                           
    def action(self, event = None):
        list = utility.window.list
        
        # Apply to the following torrents
        torrents = list.getTorrentSelected()
        if not torrents:
            return
        
        # Warning dialog: after use this mode can't go back
        msg = _("This option greatly reduces the torrent's efficiency.\n" + \
                "Super-seed should only be used for initial seeding or for re-seeding.\n" + \
                "Super-seed mode will stay in effect until the torrent is stopped.\n" + \
                "Note that this action will only affect active seeding torrents.")
        dlg = wx.MessageDialog(None, msg, _('Warning'), wx.OK|wx.CANCEL)
        result = dlg.ShowModal()
        dlg.Destroy()
        
        # Change to super seeding
        if result == wx.ID_OK:
            for torrent in torrents:
                torrent.connection.superSeed()
                
        # Focus
        list.SetFocus()
            
    def command(self, command):        
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        for torrent in torrents:
            torrent.connection.superSeed(caller="web")
        return feedback        
            
class HashCheck(Action):
    """
    Perform torrent hash checking on the selected torrents
    """
    def __init__(self):
        Action.__init__(self,
                        menudesc = _('Hash Check')+'\tShift+H')
                           
    def action(self, event = None):
        utility.actionhandler.procHASHCHECK(utility.window.list.getTorrentSelected())
        utility.window.list.SetFocus()

    def command(self, command):
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        utility.actionhandler.procHASHCHECK(torrents)
        return feedback        

class Scrape(Action):
    def __init__(self):
        Action.__init__(self, 
                        'scrape.png', 
                        shortdesc = _('Scrape'),
                        longdesc = _('Get current number of seeds and peers'),
                        menudesc = _('Current Seeds/Peers'))
                           
    def action(self, event = None):
        # Multi-selected torrent scraping
        failed = []
        for torrent in utility.window.list.getTorrentSelected():
            result = torrent.actions.scrape(faildialog = False, manualscrape = True)
            if not result:
                failed.append(torrent.getTitle())
        if failed:
            content = _('Please wait at least 1 minute before scraping again') + "\n\n"
            for item in failed:
                content += item + "\n"
            dlg = wx.MessageDialog(None,
                                   content,
                                   _('Error'),
                                   wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()

class UpdateTracker(Action):
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Update Tracker'))

    def action(self, event = None):
        for torrent in utility.window.list.getTorrentSelected():
            torrent.connection.reannounce()

class FinishAllocation(Action):
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Finish Allocation'))

    def action(self, event = None):
        for torrent in utility.window.list.getTorrentSelected():
            if torrent.status.isActive() and  torrent.connection.engine.dow.storagewrapper is not None:
                torrent.connection.engine.dow.storagewrapper.bgalloc()

##########################################################################
#   Move
##########################################################################

class MoveUp(Action):
    """
    Move torrents up in the list
    """
    def __init__(self):
        Action.__init__(self, 
                        'moveup.png', 
                        _('Move Up'))
        
    def action(self, event = None):
        list = utility.window.list
        selected = list.getSelected()
        
        newloc = utility.queue.MoveItems(selected, -1)
        list.updateSelected(selected, newloc)
        
    def command(self, command):       
        feedback = {}
        torrents = utility.commands.getTorrentsFromCommand(command)
        selected = [torrent.listindex for torrent in torrents]
        utility.queue.MoveItems(selected, -1)
        return feedback
        
class MoveDown(Action):
    """
    Move torrents down in the list
    """
    def __init__(self):
        Action.__init__(self, 
                        'movedown.png', 
                        _('Move Down'))
        
    def action(self, event = None):
        list = utility.window.list
        selected = list.getSelected()

        newloc = utility.queue.MoveItems(selected, 1)
        list.updateSelected(selected, newloc)

    def command(self, command):
        feedback = {}        
        torrents = utility.commands.getTorrentsFromCommand(command)
        selected = [torrent.listindex for torrent in torrents]
        utility.queue.MoveItems(selected, 1)
        return feedback
        
        
class MoveBottom(Action):
    """
    Move torrents to the bottom of the list
    """
    def __init__(self):
        Action.__init__(self,
                        'movebottom.png', 
                        _('Move Bottom'))
        
    def action(self, event = None):
        list = utility.window.list
        selected = list.getSelected()
               
        if selected:
            numberSelected = len(selected)
            movelist = [selected[i] - i for i in range(numberSelected)]
            utility.queue.MoveItemsBottom(movelist)
            
            listSize = list.GetItemCount()
            newloc = range(listSize - 1, listSize - numberSelected - 1, -1)
            list.updateSelected(selected, newloc)

    def command(self, command):
        feedback = {}       
        torrents = utility.commands.getTorrentsFromCommand(command)
        selected = [torrent.listindex for torrent in torrents]
        if selected:
            numberSelected = len(selected)
            movelist = [selected[i] - i for i in range(numberSelected)]
            utility.queue.MoveItemsBottom(movelist)       
        return feedback
        
class MoveTop(Action):
    """
    Move torrents to the top of the list
    """
    def __init__(self):
        Action.__init__(self, 
                        'movetop.png', 
                        _('Move Top'))
        
    def action(self, event = None):
        list = utility.window.list
        selected = list.getSelected()
       
        if selected:
            numberSelected = len(selected)
            movelist = [selected[numberSelected - i - 1] + i for i in range(numberSelected)]
            utility.queue.MoveItemsTop(movelist)

            list.updateSelected(selected, range(numberSelected))

    def command(self, command):
        feedback = {}
        torrents = utility.commands.getTorrentsFromCommand(command)
        selected = [torrent.listindex for torrent in torrents]
        if selected:
            numberSelected = len(selected)
            movelist = [selected[numberSelected - i - 1] + i for i in range(numberSelected)]
            utility.queue.MoveItemsTop(movelist)
        return feedback

##########################################################################
#   Others
##########################################################################

class Separator(Action):
    """
    Basic separator
    """
    def __init__(self):
        Action.__init__(self, 
                        'separator.png',
                        shortdesc = _('Separator'),
                        )
                               
        self.menudesc = "--------------"
                                    
class SaveTorrent(Action):
    """
    Save the torrent meta file
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Save Torrent')+'\tCtrl+S',
                        id = wx.ID_SAVE)
                           
    def action(self, event = None):        
        torrentselected = utility.window.list.getTorrentSelected(reverse = True)
        if not torrentselected:
            return

        # Choose the destination folder
        dialog = wx.DirDialog(None, 
                              _('Choose a location for the .torrent file'), 
                              '', 
                              style = wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
        result = dialog.ShowModal()
        destfolder = dialog.GetPath()
        dialog.Destroy()
        
        if result != wx.ID_OK:
            return
        
        for torrent in torrentselected:
            filename = os.path.split(torrent.src)[1]
            destname = os.path.join(destfolder, filename)
            # Check if the file to be moved already exists in destination folder
            fileexists = os.access(destname, os.F_OK)
            if fileexists:
                message = "Torrent : " + torrent.files.filename + \
                          "\n File : " + filename + "\n" + \
                          _("A file with the same name already exists in the destination folder.\nDo you want to overwrite it?")
                dialog = wx.MessageDialog(None, 
                                          message, 
                                          _('Duplicate file name'), 
                                          wx.YES_NO|wx.ICON_EXCLAMATION)
                result = dialog.ShowModal()
                dialog.Destroy()
                if(result == wx.ID_NO):
                    continue

            # Move the torrent file                        
            try:
                copy(torrent.src, destname)
            except:
                message = "Torrent : " + torrent.files.filename + "\n File : " + filename + "\n" + \
                          _('Error occurred while trying to copy the file')
                dialog = wx.MessageDialog(None, 
                                          message, 
                                          _('Error'), 
                                          wx.ICON_ERROR)
                dialog.ShowModal()
                dialog.Destroy()
                
class OpenIncoming(Action):
    """
    Open the default download folder
    """
    def __init__(self):
        Action.__init__(self, 
                        'incoming.png', 
                        shortdesc = _('Incoming'), 
                        menudesc = _('&Open Incoming'),
                        )
                           
    def action(self, event = None):
        dldir = utility.config.Read('defaultfolder')
        try:
            utility.open_new(dldir)
        except:
            dialog = wx.MessageDialog(utility.frame, 
                                      _('Error occurred while trying to open the incoming folder'), 
                                      _('Error'), 
                                      wx.ICON_ERROR)
            dialog.ShowModal()
            dialog.Destroy()
            
class OpenDest(Action):
    """
    Open the download destination folder
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Open Destination')+'\tShift+O')
                           
    def action(self, event = None):
        for torrent in utility.window.list.getTorrentSelected(firstitemonly = True):
            if not torrent.files.onOpenDest():
                utility.window.list.SetFocus()
                
class OpenFileDest(Action):
    """
    Lunch the first file in the torrent
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Open File'))
                           
    def action(self, event = None):
        for torrent in utility.window.list.getTorrentSelected(firstitemonly = True):
            if not torrent.files.onOpenFileDest():
                return
                
class ChangeDest(Action):
    """
    Open the change destination dialog
    """
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Change Destination'))
                           
    def action(self, event = None):                
        torrentselected = utility.window.list.getTorrentSelected()
        
        # All selected torrents must be inactive to proceed
        inactivestopped = stopTorrentsIfNeeded(torrentselected)
        if not inactivestopped:
            return
        
        for torrent in torrentselected:
            if not torrent.dialogs.changeDest():
                utility.window.list.SetFocus()
                break                

class ChangePriority(Action):
    def __init__(self):
        Action.__init__(self, 
                        menudesc = _('Priority'))
                           
        self.priorities = [_('Highest'), _('High'), _('Normal'), _('Low'), _('Lowest')]
        self.prioID = {}
        for prio in self.priorities:
            self.prioID[prio] = wx.NewId()
                           
    def action(self, event = None):
        list = utility.window.list
        selected = list.getTorrentSelected()
               
        newprio = None
        for prio in self.priorities:
            id = self.prioID[prio]
            if id == event.GetId():
                newprio = self.priorities.index(prio)
            
        for torrent in selected:
            torrent.changePriority(newprio)
        
        list.SetFocus()
        
    def getCurrentPrio(self, prio = None):
        list = utility.window.list
        selected = list.getTorrentSelected(firstitemonly = True)
        
        if not selected:
            return None
            
        torrent = selected[0]
        
        prio = torrent.prio
        if prio is None:
            prio = utility.config.Read('defaultpriority')

        return self.priorities[prio]
               
    def addToMenu(self, menu, bindto = None):
        if bindto is None:
            bindto = menu

        currentprio = self.getCurrentPrio()
        if currentprio is None:
            return
            
        priomenu = wx.Menu()
            
        for prio in self.priorities:
            id = self.prioID[prio]
            bindto.Bind(wx.EVT_MENU, self.action, id = id)
            if wx.Platform == "__WXGTK__":
                priomenu.Bind(wx.EVT_MENU, self.action, id = id)
            priomenu.Append(id, prio, prio, wx.ITEM_RADIO)

        priomenu.Check(self.prioID[currentprio], True)

        menu.AppendMenu(self.id, self.menudesc, priomenu)
        
        return self.id
